package com.yihaodian.index.meta.routing;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yihaodian.common.util.NetUtil;
import com.yihaodian.index.meta.shard.Shard;
import com.yihaodian.index.meta.shard.ShardRouting;

public class RoutingTables {
	/**
	 * <Index, Routing>
	 */
	ImmutableMap<String, RoutingTable> _routingMap = null;

	RoutingTables() {

	}

	public RoutingTables(ImmutableMap<String, RoutingTable> routing) {
		this._routingMap = routing;
	}

	public RoutingTable routingTable(String index) {
		return _routingMap.get(index);
	}

	public Collection<ShardRouting> getShardRouting(String nodeId) {
		List<ShardRouting> shards = Lists.newArrayList();

		Set<String> keys = _routingMap.keySet();
		for (String key : keys) {
			RoutingTable routingTable = _routingMap.get(key);
			Collection<ShardRouting> shrds = routingTable.getShardRouting(nodeId);

			// for 127.0.0.1 test
			if (shrds == null || shrds.isEmpty()) {
				String host = NetUtil.localAddress();
				nodeId = nodeId.replace(host, "127.0.0.1");
				shrds = routingTable.getShardRouting(nodeId);
			}

			shards.addAll(shrds);
		}

		return shards;
	}

	public Set<String> indexNames() {
		return _routingMap.keySet();
	}

	// public static RoutingTables build(Collection<Node> nodes, String
	// clusterId) {
	// Map<String, RoutingTable> maps = new HashMap<String, RoutingTable>();
	// RoutingTables rts = null;
	// if (nodes != null && nodes.size() > 0) {
	// for (Node node : nodes) {
	// if (node.getShards() != null && node.getShards().size() > 0) {
	// for (Shard shard : node.getShards()) {
	// String index = shard.getIndexId();
	// RoutingTable rt = maps.get(index);
	// if (rt == null) {
	// rt = new RoutingTable(index, clusterId);
	// }
	// rt.addEntry(node.getId(), shard);
	// maps.put(index, rt);
	// }
	// }
	//
	// }
	// rts = new RoutingTables.Builder(maps).build();
	// }
	// return rts;
	// }

	public static class Builder {
		Map<String, RoutingTable> maps = new HashMap<String, RoutingTable>();

		public Builder() {
			maps = Maps.newHashMap();
		}

		public Builder(Map<String, RoutingTable> maps) {
			this.maps = maps;
		}

		public Builder(RoutingTables rts) {
			if (rts._routingMap == null)
				this.maps = Maps.newHashMap();
			else
				this.maps = new HashMap<String, RoutingTable>(rts._routingMap);
		}

		public Builder add(RoutingTable rt) {
			maps.put(rt.getIndexId(), rt);

			return this;
		}

		public Builder remove(String index) {
			maps.remove(index);

			return this;
		}

		public RoutingTables build() {
			if (maps == null)
				maps = new HashMap<String, RoutingTable>();
			return new RoutingTables(
					new ImmutableMap.Builder<String, RoutingTable>().putAll(
							maps).build());
		}
	}
}
